當叢集裡有很多node及pod時,如果想把相同或是相關的服務部屬到同一個node上時該怎麼做呢?
在這裡Pod元件提供了親和性(Affinity)屬性,當然對Deployment也適用,可將服務部屬到有相關標籤的服務所在node上,當然也提供了反親和性(Anti-Affinity),可以避免將把相同的服務部屬到同一個node上,那麼就讓我們來看看要如何實做吧!
※Pod 環境必需(完全)滿足 Pod 相依/互斥配置才可進行派送,否則將創建失敗
※podAffinity 設定為參考 Pod 部署,則 podAntiAffinity 禁止與參考 Pod 部署
mysql.yaml
kubectl apply -f mysql.yaml
apiVersion: v1
kind: Pod
metadata:
name: mysql-1
labels:
app: mysql
spec:
containers:
- image: mysql:5.6
name: mysql
env:
# Use secret in real usage
- name: MYSQL_ROOT_PASSWORD
value: password
kubectl get pod -o wide
kubectl get node --show-labels
※Pod affinity 擁有 Node domain (Label) 的分別,需指定 topologyKey (domain)
※參考 kubectl get node --show-labels 的資料
撰寫 相依於 mysql & mongodb 的兩個服務 yaml 檔案nginx-mysql.yaml
&nginx-mongodb.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-mysql
labels:
app: nginx
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- mysql
topologyKey: name
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
hostPort: 80
apiVersion: v1
kind: Pod
metadata:
name: nginx-mongodb
labels:
app: nginx
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- mongodb
topologyKey: name
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
hostPort: 80
※附註說明
部屬相依於 mysql & mongodb 的兩個服務 yaml 檔案nginx-mysql.yaml
&nginx-mongodb.yaml
kubectl apply -f nginx-mysql.yaml
kubectl apply -f nginx-mongodb.yaml
kubectl get pod -o wide
因無法找到 Pod affinity 參考 Pod 的服務 Labels,Pod 無法進行派送與啟動
nginx-anti-affinity.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-anti
labels:
app: nginx
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- mysql
topologyKey: name
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
hostPort: 80
kubectl apply -f nginx-anti-affinity.yaml
kubectl get pod -o wide
※Pod 參考需求環境派送,若無法匹配則尋找最低負載 Node 部屬 Pod
※podAffinity 設定為參考 Pod 部署,則 podAntiAffinity 禁止與參考 Pod 部署
mysql.yaml
kubectl apply -f mysql.yaml
apiVersion: v1
kind: Pod
metadata:
name: mysql-1
labels:
app: mysql
spec:
containers:
- image: mysql:5.6
name: mysql
env:
# Use secret in real usage
- name: MYSQL_ROOT_PASSWORD
value: password
kubectl get pod -o wide
kubectl get node --show-labels
撰寫 相依於 mysql & mongodb 的兩個服務 yaml 檔案nginx-mysql-soft.yaml
&nginx-mongodb-soft.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-mysql-soft
labels:
app: nginx
spec:
affinity:
podAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- mysql
topologyKey: name
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
hostPort: 80
apiVersion: v1
kind: Pod
metadata:
name: nginx-mongodb-soft
labels:
app: nginx
spec:
affinity:
podAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- mongodb
topologyKey: name
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
hostPort: 80
※附註說明
派送服務 yaml 檔
kubectl apply -f nginx-mysql-soft.yaml
kubectl apply -f nginx-mongodb-soft.yaml
kubectl get pod -o wide
※若參考 Pod 的服務 Labels 無法對應,則尋找負載較低的 Node 進行派送與啟動
mysql-deployment.yaml
kubectl apply -f mysql-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
spec:
replicas: 2
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- image: mysql:5.6
name: mysql
env:
# Use secret in real usage
- name: MYSQL_ROOT_PASSWORD
value: password
kubectl get deploy -o wide
kubectl get pod -o wide
kubectl get rs
撰寫一個服務 yaml 檔nginx-anti-affinity-soft.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-anti-soft
labels:
app: nginx
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- mysql
topologyKey: name
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
hostPort: 80
派送服務互斥 mysql 服務
kubectl apply -f nginx-anti-affinity-soft.yaml
kubectl get pod -o wide
所有 Node 皆有 mysql Pod 服務,則尋找負載較低的 Node 進行派送與啟動
※測試方案 : 將node Affinity 的 hardMode和pod Affinity 的 hardMode同時配置並執行派送
kubectl get node --show-labels
kubectl get pod -o wide
nginx-mysql-node-pod-affinity-hard.yaml
&nginx-mongodb-node-pod-affinity-hard.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-mysql-node-pod-affinity-hard
labels:
app: nginx
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: disktype
operator: In
values:
- hdd
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- mysql
topologyKey: name
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
hostPort: 80
apiVersion: v1
kind: Pod
metadata:
name: nginx-mongodb-node-pod-affinity-hard
labels:
app: nginx
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: disktype
operator: In
values:
- hdd
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- mongodb
topologyKey: name
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
hostPort: 80
kubectl apply -f nginx-mysql-node-pod-affinity-hard.yaml
kubectl apply -f nginx-mongodb-node-pod-affinity-hard.yaml
kubectl get pod -o wide
成功派送 Pod 至符合規定配置的 Node
因無法找到匹配的需求設置,Pod 無法進行派送與啟動